package com.qiangesoft.design.behavioral.responsibilitychain;

import java.util.HashMap;
import java.util.Map;

/**
 * 客户类
 *
 * ps:责任链模式
 */
public class Chain {

    public static void main(String[] args) {
        // 模拟请求
        Request request = new Request();
//        request.setPath("/api/news");
        request.setPath("/user/1");
        Map<String, String> header = new HashMap<>();
        header.put("token", "111111");
        request.setHeader(header);

        // 组装责任链
        Handler handler = getHandlerChain();

        // 提交请求
        handler.doHandler(request);

        System.out.println("***执行了接口方法***");
    }

    /**
     * 组装责任链
     *
     * @return
     */
    private static Handler getHandlerChain() {
        Handler tokenHandler = new TokenHandler();
        Handler authHandler = new AuthHandler();
        Handler logHandler = new LogHandler();
        tokenHandler.setNext(authHandler)
                .setNext(logHandler);
        return tokenHandler;
    }
}

/**
 * 抽象处理者
 */
abstract class Handler {

    protected Handler next;

    public Handler setNext(Handler next) {
        this.next = next;
        return next;
    }

    protected abstract void doHandler(Request request);
}

/**
 * 具体处理者：token校验
 */
class TokenHandler extends Handler {
    @Override
    public void doHandler(Request request) {
        // 有些接口无需登录
        String path = request.getPath();
        if (path.startsWith("/api")) {
            return;
        }

        try {
            // token校验（模拟）
            String token = request.getHeader().get("token");
            if (token == null || "".equals(token)) {
                System.out.println("用户未登录！");
                return;
            }
            if (!"111111".equals(token)) {
                System.out.println("登录已失效!");
                return;
            }
            String username = "admin";
            AuthenticationContextHolder.set(username);
            System.out.println("token校验成功!");

            if (next != null) {
                next.doHandler(request);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            AuthenticationContextHolder.remove();
        }
    }
}

/**
 * 具体处理者：权限校验
 */
class AuthHandler extends Handler {
    @Override
    public void doHandler(Request request) {
        String username = AuthenticationContextHolder.get();
        if (!"admin".equals(username)) {
            System.out.println("当前用户无权限!");
            return;
        }

        System.out.println("权限校验成功！");

        if (next != null) {
            next.doHandler(request);
        }
    }
}

/**
 * 具体处理者：日志记录
 */
class LogHandler extends Handler {
    @Override
    public void doHandler(Request request) {
        String username = AuthenticationContextHolder.get();
        System.out.println("记录日志：请求【xxx接口】 操作人【" + username + "】！");

        if (next != null) {
            next.doHandler(request);
        }
    }
}

/**
 * 模拟request对象
 */
class Request {

    private String path;

    private Map<String, String> header;

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public Map<String, String> getHeader() {
        return header;
    }

    public void setHeader(Map<String, String> header) {
        this.header = header;
    }
}

/**
 * 线程本地变量：登录用户信息
 */
class AuthenticationContextHolder {
    private static final ThreadLocal<String> CURRENT_USER = new ThreadLocal<>();

    public static String get() {
        return CURRENT_USER.get();
    }

    public static void set(String user) {
        CURRENT_USER.set(user);
    }

    public static void remove() {
        CURRENT_USER.remove();
    }
}